package com.example.springbootblog.common.advice;

import com.example.springbootblog.common.pojo.result.Result;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * 统一结果返回
 *
 * 注意这里不需要加上泛型， 使用Object 接收即可
 */


@Slf4j
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {


    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        // 为 true 表示执行统一结果
        return true;
    }

//    操作String 转化为 JSON 对象
    @Autowired
    ObjectMapper objectMapper;

//    序列化： 将String 转化为 JSON
//    ObjectMapper mapper = new ObjectMapper();
//    String jsonString = mapper.writeValueAsString(myObject);


//  反列化
//    ObjectMapper mapper = new ObjectMapper();
//    MyObject myObject = mapper.readValue(jsonString, MyObject.class);

    @Override
    @SneakyThrows

    /**
     * @SneakyThrows 作用： 隐藏抛出的异常的
     * 但是会使程序在出现BUG时，难以发现错误。
     */
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
//        自己就是Result 就直接返回
        if(body instanceof Result) {
            return  body;
        }

//        进行转化
        if (body instanceof  String) {
            try {
                return  objectMapper.writeValueAsString(Result.ok(body));
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }

//        封装Result数据返回
        return Result.ok(body);
    }
}
